package com.attilax.namespace;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONArray;

import com.attilax.coll.ListX;
import com.attilax.collection.listUtil;
import com.attilax.io.dirx;
import com.attilax.io.filex;
import com.attilax.jar.JarFileView;
import com.attilax.json.JSONObject;
import com.attilax.lang.Closure;
import com.attilax.lang.MapX;
import com.attilax.lang.text.RegExpChar4splitor;
import com.attilax.lang.text.strUtil;
import com.attilax.office.excelUtil;
import com.attilax.text.CamelStrUtil;
import com.attilax.util.numUtil;

public class NamespaceUtil {

	private String traveMode;

	public static void main(String[] args) throws Exception {
		// ["com.attilax","camel","Gbnfm","hhh","comm"]
//		String s = "com.attilax_camelXGbnfm-hhh/comm$123";
//		// s="CamelGbnfm";
//		List<String> li = toList_byDotByCase(s);
//		System.out.println(JSONObject.fromObject(li).toString(2));
//
 	String strPath = "D:\\workspace 空格\\AtiPlatf\\WEB-INF\\lib\\t";
		// calcPkg(strPath);
		// calcCls(strPath);
		NamespaceUtil nc = new NamespaceUtil();
		nc.traveMode = "meth";
		Map m = new NamespaceUtil().traveCalcNames(strPath);
		List Li_table = listUtil.addAll(m);
		new excelUtil().toExcel(Li_table, "c:\\calc_Meth_" + filex.getUUidName()
				+ ".xls");
		System.out.println("--f");

	}
	int jarNum=0;
	@SuppressWarnings("rawtypes")
	private Map traveCalcNames(String strPath) {
		final Closure trave_executor_forMeths = new Closure() {

			@Override
			public Object execute(Object arg0) throws Exception {
				String meth = (String) arg0;
				List<String> nams = new ClassNameSplitor().split(meth);
				for (String nam : nams) {
				//	final String nam2 = nam;
					final String nam_key = strUtil
							.getSingleFmt(nam, extMultiTrimWords)
							.toLowerCase().trim();
					if (filted(nam_key))
						continue;
					Map row = tab.get(nam_key);
					if (row == null) {
						tab.put(nam_key, new HashMap() {
							{

								this.put("name", nam_key);
								this.put("count", 0);
							}
						});// add new row
					}
					row = tab.get(nam_key);
					// new HashMap<String,Integer>();
					row.put("count", MapX.get(row, "count", 0) + 1);
				}

				return null;
			}
		};
		final Closure jar_file_trave_executor_forClass = new Closure() {

			@Override
			public Object execute(Object arg0) throws Exception {
			
				String classNameFullPath = arg0.toString();
				if ("META-INF/".toLowerCase().equals(
						classNameFullPath.toLowerCase()))
					return null;
				if (classNameFullPath.startsWith("META-INF"))
					return null;
				classNameFullPath = classNameFullPath.replace("/", ".");
				traveClassMeths(classNameFullPath, trave_executor_forMeths);
			 
				return null;
			}

			private void traveClassMeths(String cls,
					Closure trave_executor_forMeths) {
				cls=filex.getFileName_noExtName(cls);
				Class classType;
				try {
					classType = Class.forName(cls);
					System.out.println("-----loadok class ok:"+cls);
				} catch (ClassNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					throw new RuntimeException(e);
				}

				Method[] methods = classType.getDeclaredMethods();

				for (Method methed : methods) {

					// System.out.println(methed);
					methed.setAccessible(true);

					String name = methed.getName();
					try {
						trave_executor_forMeths.execute(name);
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					System.out.println(name);

				}
//				int spalashIdx = cls.lastIndexOf("/");
//				String className = cls.substring(spalashIdx + 1, cls.length());
//				String classMainName = className.split("\\.")[0];
//				System.out.println(cls);

			}
		};
		
		new dirx().setTraveMode(this.traveMode).trave(strPath, new Closure() {

			@Override
			public Object execute(Object arg0) throws Exception {
				String jar = (String) arg0;
				jarNum++;
				System.out.println("*********start trave jar num:"+String.valueOf(jarNum));
				if (!jar.toLowerCase().endsWith("jar"))
					return jar;// continue
				JarFileView jfv = new JarFileView(jar);

				jfv.setTraveMode("file").trave(jar,
						jar_file_trave_executor_forClass);

				return null;
			}

		});
		return tab;
		// return null;
	}

	private static void calcCls(String strPath) throws Exception {
		Map m = new NamespaceUtil().traveClassCalcNames(strPath);
		List Li_table = listUtil.addAll(m);
		// System.out.println(
		// com.attilax.json.JSONArray.fromObject(Li_table).toString(2));
		excelUtil.toExcel("名字,计数", "name,count", Li_table, "c:\\calc_cls_"
				+ filex.getUUidName() + ".xls");

	}

	private static void calcPkg(String strPath) throws Exception {
		Map m = new NamespaceUtil().travePkgCalcNames(strPath);
		List Li_table = listUtil.addAll(m);
		System.out.println(com.attilax.json.JSONArray.fromObject(Li_table)
				.toString(2));
		excelUtil.toExcel("名字,计数", "name,count", Li_table, "c:\\calc_pkg_"
				+ filex.getUUidName() + ".xls");
	}

	public static List<String> toList_byDotByCase(String clazzName) {
		List<String> li_splitor = new ArrayList<String>();
		li_splitor.add(RegExpChar4splitor.dot);
		li_splitor.add("-");
		li_splitor.add("_");
		li_splitor.add("/");
		li_splitor.add(RegExpChar4splitor.dollar);

		List<String> li = new ArrayList<String>();
		String[] a = strUtil.splitByMultiChar(clazzName, li_splitor);
		for (String pkgItem : a) {
			pkgItem = pkgItem.trim();
			if (numUtil.isNum(pkgItem))
				continue;
			// List li2=CamelStrUtil.camelCase2List(pkgItem);
			li.add(pkgItem);
		}

		return li;
	}

	/**
	 * for pkg
	 */
	final Closure jar_file_trave_executor = new Closure() {

		@Override
		public Object execute(Object arg0) throws Exception {
			String pkg = arg0.toString();
			if ("META-INF/".toLowerCase().equals(pkg.toLowerCase()))
				return null;
			if (pkg.startsWith("META-INF"))
				return null;
			pkg = pkg.replace("/", ".");
			System.out.println(pkg);
			List<String> nams = new ClassNameSplitor().split(pkg);
			for (String nam : nams) {
				final String nam2 = nam;
				String nam_key = strUtil.getSingleFmt(nam2, extMultiTrimWords)
						.toLowerCase().trim();
				if (nam_key.length() > 5)
					nam_key = nam_key.substring(0, 5);
				if (filted(nam_key))
					continue;
				Map row = tab.get(nam_key);
				final String nam_key_final = nam_key;
				if (row == null) {
					tab.put(nam_key, new HashMap() {
						{

							this.put("name", nam_key_final);
							this.put("count", 0);
						}
					});// add new row
				}
				row = tab.get(nam_key);
				// new HashMap<String,Integer>();
				row.put("count", MapX.get(row, "count", 0) + 1);
				// m.put m.get(nam)
			}
			return null;
		}
	};

	public String extMultiTrimWords = "access,aaaaaaaa,class";

	final Closure jar_file_trave_executor_forClass = new Closure() {

		@Override
		public Object execute(Object arg0) throws Exception {
			String pkg = arg0.toString();
			if ("META-INF/".toLowerCase().equals(pkg.toLowerCase()))
				return null;
			if (pkg.startsWith("META-INF"))
				return null;
			int spalashIdx = pkg.lastIndexOf("/");
			String className = pkg.substring(spalashIdx + 1, pkg.length());
			String classMainName = className.split("\\.")[0];
			System.out.println(pkg);
			List<String> nams = new ClassNameSplitor().split(classMainName);
			for (String nam : nams) {
				final String nam2 = nam;
				final String nam_key = strUtil
						.getSingleFmt(nam2, extMultiTrimWords).toLowerCase()
						.trim();
				if (filted(nam_key))
					continue;
				Map row = tab.get(nam_key);
				if (row == null) {
					tab.put(nam_key, new HashMap() {
						{

							this.put("name", nam_key);
							this.put("count", 0);
						}
					});// add new row
				}
				row = tab.get(nam_key);
				// new HashMap<String,Integer>();
				row.put("count", MapX.get(row, "count", 0) + 1);
				// m.put m.get(nam)
			}
			return null;
		}
	};
	final Map<String, Map> tab = new HashMap<String, Map>();

	public Map travePkgCalcNames(String strPath) {

		// final List<Map> m=new ArrayList<Map>();
		// trav jar file
		new dirx().traveFile_noIncDir(strPath, new Closure() {

			@Override
			public Object execute(Object arg0) throws Exception {
				String jar = (String) arg0;
				if (!jar.toLowerCase().endsWith("jar"))
					return jar;// continue
				JarFileView jfv = new JarFileView(jar);

				jfv.travePkg(jar, jar_file_trave_executor);

				return null;
			}

		});
		return tab;

	}

	/**
	 * too short or is num name
	 * @param nam_key
	 * @return
	 */
	protected boolean filted(String nam_key) {
		if (numUtil.isNum(nam_key))
			return true;
		if (nam_key.length() <= 1)
			return true;
		return false;
	}

	public Map traveClassCalcNames(String strPath) {
		// final Map<String,Map> tab=new HashMap<String, Map>();

		// final List<Map> m=new ArrayList<Map>();
		// trav jar file
		new dirx().traveFile_noIncDir(strPath, new Closure() {

			@Override
			public Object execute(Object arg0) throws Exception {
				String jar = (String) arg0;
				if (!jar.toLowerCase().endsWith("jar"))
					return jar;// continue
				JarFileView jfv = new JarFileView(jar);

				jfv.travClassFile(jar, jar_file_trave_executor_forClass);

				return null;
			}

		});
		return tab;

	}

	public Map traveAllCalcNames() {
		return null;

	}

}
